using System;
using System.Collections.Generic;
using System.Linq;
using T.FAS.Runtime.Metadata.Entity.DataModel;
using T.FAS.Runtime.DataAccess.SQLDom;
using T.FAS.Runtime.DataAccess.Common;
using T.FAS.Runtime.Base.Entity;

namespace T.FAS.Runtime.DataAccess.Engine
{
    /// <summary>
    /// 领域对象查询SQL语句构造策略
    /// </summary>
    class SelectSqlBuildStrategy : BaseSqlBuildStrategy
    {
        /// <summary>
        /// 构造不包含数据的Sql（即SqlSchema）。
        /// </summary>
        /// <param name="sqls">Sql语句对象集合。</param>
        /// <param name="context">Sql构造的上下文信息。</param>
        public override SqlStatementCollection BuildTableSqlSchema(SqlBuildingContext context)
        {
            if (context == null)
                throw new FasException(DataAccessErrorCode.Retrieve.NullValue, CommonStringClassEngine.SqlBuildStrategy_ContextCannotBeNull);

            var sqls = new SqlStatementCollection();

            SelectSqlStatement selectStatement = SQLStatementFactory.CreateSqlStatement(SqlStatementType.Select, context.DbType) as SelectSqlStatement;
            selectStatement.SqlBuildingInfo.DataSource = context.DataSource;

            //Parsing main part of query SQL statement
            BuildMainFrom(selectStatement, context.CommonObject, context.Node, context.DataObject, context.TableName, context);

            //Parsing query fields list
            BuildQueryFieldList(selectStatement, context.Node, context.DataObject, context.ControlContext);

            //Parsing inner join clause
            BuildMainInnerJoin(selectStatement, context);

            sqls.Add(selectStatement);

            return sqls;
        }

        /// <summary>
        /// 在SqlSchema基础上，构造包含数据的Sql。
        /// </summary>
        /// <param name="sqls">Sql语句对象集合。</param>
        /// <param name="context">Sql构造的上下文信息。</param>
        public override void BuildTableSqlDetail(SqlStatementCollection sqls, SqlBuildingContext context)
        {
            var sql = sqls.FirstOrDefault(x => x.SqlBuildingInfo.TableName == context.TableName);
            if (sql == null) return;

            var querySQL = sql as SelectSqlStatement;

            //Parsing left join clause of query SQL statement
            BuildSQLJoin(querySQL, context);

            //Parsing where clause of query SQL statement
            BuildSQLCondition(querySQL, context);
        }

        public void BuildSQLJoin(SelectSqlStatement sql, SqlBuildingContext context)
        {
            //获取到当前节点的关联关系，排除主从类型的关联
            var associations = context.Node.Associations.Where(i => i.AssociateType == AssociateType.OuterLeftJoin);
            if (associations == null || associations.Count() == 0) return;

            foreach (var association in associations)
            {
                HandlingLeftOuterJoinAssociation(sql, context, association);
            }
        }

        /// <summary>
        /// 处理外键关联
        /// </summary>
        /// <param name="sql">Select语句</param>
        /// <param name="context">SQL构造上下文</param>
        /// <param name="association">关联</param>
        private void HandlingLeftOuterJoinAssociation(SelectSqlStatement sql, SqlBuildingContext context, Association association)
        {
            /*低代码改动：外键关联DO改造*/
            if (association.AssoDataObject == null)
                throw new FasException(DataAccessErrorCode.CompositeDataObject.AssociationError, string.Format(CommonStringClassEngine.SelectSqlBuildStrategy_HandlingLeftOuterJoinAssociation,association.ID,association.AssoDataObjectID));

            //外键关联中使用的SqlTable,通过关联的ID进行标识，存在一个节点上的多个元素关联同一个表的情况
            /***********低代码改动:更改SqlTable注册逻辑，修改key为CNO.ID，提前注入TableAlias***********/
            var SqlTableMappingKey = association.ID;
            var tableAlias = association.AssoDataObjectTableAlias;

            SqlTable associatedSqlTable = base.FindSqlTable(SqlTableMappingKey, sql.SqlBuildingInfo);
            if (associatedSqlTable == null)
            {
                var assoTableName = context.DataObjectTableMapping[association.AssoDataObjectID]; 
                associatedSqlTable = base.TryFindAndRegistSqlTable(SqlTableMappingKey, assoTableName, tableAlias, assoTableName, sql.SqlBuildingInfo);
            }

            var childAssociation = new InternalAssociation()
            { 
                AssociatedDataObject = association.AssoDataObject,
                AssociatedTable = associatedSqlTable,
                LocatedCommonObject = sql.SqlBuildingInfo.CommonObject,
                LocatedDataObject = sql.SqlBuildingInfo.CurrentDataObject,
                LocatedNode = sql.SqlBuildingInfo.CurrentNode,
                LocatedTable = sql.SqlBuildingInfo.CurrentSqlTable,
                Association = association,
                AdditionalCondition = association.FilterCondition
            };

            AppendQueryRefFields(sql, association, childAssociation);

            BuildLeftJoin(sql, childAssociation, context);
        }

        /// <summary>
        /// Append association query fields
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="association"></param>
        /// <param name="childAssociation"></param>
        private static void AppendQueryRefFields(SelectSqlStatement sql, Association association, InternalAssociation childAssociation)
        {
            foreach (var refElement in association.RefElements)
            {
                /*低代码改动：外键关联DO改造*/
                var refcolumn = association.AssoDataObject.Columns.FirstOrDefault(i => i.ID == refElement.SourceElementID);
                if (refcolumn == null)
                    throw new Exception(string.Format(CommonStringClassEngine.SelectSqlBuildStrategy_AppendQueryRefFields,association.CompositeDataObjectID,association.CompositeNodeObjectID,refElement.SourceElementID,association?.AssoDataObjectTableAlias));
                var assElement = new InternalRefElement()
                {
                    RefColumn = refcolumn,
                    Label = refcolumn.ColumnName
                };
                childAssociation.RefElements.Add(assElement);

                var mainModelObjectElement = childAssociation.LocatedNode.Elements.FirstOrDefault(i => i.ID == refElement.TargetElementID);
                if (mainModelObjectElement == null)
                {
                    throw new Exception(string.Format(CommonStringClassEngine.SelectSqlBuildStrategy_AppendQueryRefFields1, association.CompositeDataObjectID, association.CompositeNodeObjectID, refElement.TargetElementID) +
string.Format(CommonStringClassEngine.SelectSqlBuildStrategy_AppendQueryRefFields2, childAssociation.AssociatedDataObject?.Code, refElement.SourceElementID));
                }

                var columnName = refcolumn.ColumnName;
                /* 低代码改动：外键关联字段国际化处理
                 * 启用国际化时，返回当前启用的辅助语言对应的物理存储列
                 */
                if (refcolumn.IsInternational)
                {
                    Dictionary<string, string> mapping = InternationalTools.GetLanguageMapping(InternationalMode.CurrentUser);
                    if (mapping.Count == 1)
                    {
                        columnName = InternationalTools.GetRealFieldName(association.AssoDataObject, refcolumn.ColumnName, mapping.First().Key);
                    }
                }
                var field = new SelectListField()
                {
                    Table = childAssociation.AssociatedTable,
                    IsUseAlias = true,
                    IsUseFieldPrefix = true,
                    FieldName = columnName,
                    FieldAlias = mainModelObjectElement.Alias
                };
                sql.SelectList.ChildCollection.Add(field);
            }
        }

        #region 构造和主对象之间的关联

        /// <summary>
        /// 构造查询SQL语句中表主要的内连接部分
        /// </summary>
        /// <remarks>
        /// 处理时分为几种场景：
        /// 1. 当前节点是根节点时，不做任何处理
        /// 2. 当前节点不是根节点时，此时需要和父节点进行内连接关联过滤数据（例如主从结构），
        ///    如果关联的父节点不是根节点，上级也存在父节点(例如主从从结构)，此时要进行递归循环处理
        /// 提示：
        ///    所有内连接的场景均是在同一个领域模型情形下，不可能关联到其他CO的节点。
        /// </remarks>
        /// <param name="sql">Sql语句对象</param>
        /// <param name="CompositeDataObject">通用中间对象</param>
        /// <param name="currentObject">当前解析用到的节点对象</param>
        /// <param name="dataObject">当前解析用到的节点对象对应的数据对象</param>
        public void BuildMainInnerJoin(SelectSqlStatement sql, SqlBuildingContext context)
        {
            var currentObject = context.Node;
            var dataObject = context.DataObject;
            //当前节点是根节点时, 直接返回
            //统一数据访问服务改动v1：
            //if (currentObject.IsRootObject || context.CommonObject.RootCompositeNodeObject.ID == currentObject.ID) return;

            //获取到当前节点的主从关联,主从关系中的主从关联关系是存放在子节点的关联集合上
            var associations = currentObject.Associations.Where(i => i.AssociateType == AssociateType.InnerJoin);
            if (associations == null || associations.Count() == 0) return;

            /***********低代码改动:更改SqlTable注册逻辑，修改key为CNO.ID，提前注入TableAlias***********/
            var current_SqlTableMappingKey = currentObject.ID;
            var current_tableAlias = currentObject.DataObjectTableAlias;

            var currentTableName = context.DataObjectTableMapping[dataObject.ID];
            SqlTable cTable = base.FindSqlTable(current_SqlTableMappingKey, sql.SqlBuildingInfo);
            if (cTable == null)
            {
                cTable = base.TryFindAndRegistSqlTable(current_SqlTableMappingKey, currentTableName, current_tableAlias, currentTableName, sql.SqlBuildingInfo);
            }

            /***********低代码改动:更改SqlTable注册逻辑，修改key为CNO.ID，提前注入TableAlias***********/
            var parent_SqlTableMappingKey = currentObject.ParentObject.ID;
            var parent_tableAlias = currentObject.ParentObject.DataObjectTableAlias;

            string parentDataObjectID = currentObject.ParentObject.DataObjectID;
            var parentTableName = context.DataObjectTableMapping[parentDataObjectID];
            SqlTable pTable = base.FindSqlTable(parent_SqlTableMappingKey, sql.SqlBuildingInfo);
            if (pTable == null)
            {
                pTable = base.TryFindAndRegistSqlTable(parent_SqlTableMappingKey, parentTableName, parent_tableAlias, parentTableName, sql.SqlBuildingInfo);
            }

            var innerJoin = new InnerJoinItem();
            innerJoin.InnerJoinTable = pTable;

            foreach (Association association in associations)
            {
                foreach (var item in association.Items)
                {
                    var srcElement = currentObject.Elements.FirstOrDefault(i => i.ID == item.SourceElementID);
                    var srcColumn = dataObject.Columns.FirstOrDefault(i => i.ID == srcElement.DataColumnID);
                    if (srcColumn == null)
                        throw new FasException(DataAccessErrorCode.CompositeDataObject.ColumnError, CommonStringClassEngine.SelectSqlBuildStrategy_BuildMainInnerJoin_CannotFindInnerJoinColumn+ srcElement.DataColumnID);

                    var targetElement = currentObject.ParentObject.Elements.FirstOrDefault(i => i.ID == item.TargetElementID);
                    var targetColumn = currentObject.ParentObject.DataObject.Columns.FirstOrDefault(i => i.ID == targetElement.DataColumnID);
                    if (srcColumn == null)
                        throw new FasException(DataAccessErrorCode.CompositeDataObject.ColumnError, CommonStringClassEngine.SelectSqlBuildStrategy_BuildMainInnerJoin_CannotFindInnerJoinColumn + targetElement.DataColumnID);

                    var joinItem = new JoinConditionItem();
                    joinItem.LeftField = new ConditionField();
                    joinItem.RightField = new ConditionField();

                    joinItem.LeftField.Table = cTable;
                    joinItem.LeftField.IsUseFieldPrefix = true;
                    joinItem.LeftField.FieldName = srcColumn.ColumnName;

                    joinItem.RightField.Table = pTable;
                    joinItem.RightField.IsUseFieldPrefix = true;
                    joinItem.RightField.FieldName = targetColumn.ColumnName;

                    innerJoin.ChildCollection.Add(joinItem);
                }

                sql.MainFromItem.ChildCollection.Add(innerJoin);

                //如果关联的父节点上还有存在父级节点，递归进行处理,直至根节点退出 
                //if (association.AssoCompositeNodeObject.ParentObject != null)
                //{
                //    context.Node = association.AssoCompositeNodeObject.ParentObject;
                //    context.DataObject = association.AssoCompositeNodeObject.ParentObject.DataObject;
                //    BuildMainInnerJoin(sql, context);
                //}
                if (association.AssoCompositeNodeObject.Associations != null && association.AssoCompositeNodeObject.Associations.Count > 0)
                {
                    context.Node = association.AssoCompositeNodeObject;
                    context.DataObject = association.AssoCompositeNodeObject.DataObject;
                    BuildMainInnerJoin(sql, context);
                }
            }
        }

        /// <summary>
        /// 构造查询主体部分
        /// </summary>
        /// <remarks>查询主体是一个子查询，为了支持一个数据对象多个数据库表</remarks>
        /// <param name="sql">Select语句</param>
        /// <param name="CompositeDataObject">通用中间对象</param>
        /// <param name="CompositeNodeObject">当前节点</param>
        /// <param name="dataObject">当前节点对应的数据对象</param>
        private void BuildMainFrom(SelectSqlStatement sql, CompositeDataObject CompositeDataObject, CompositeNodeObject CompositeNodeObject, DataObject dataObject, string tableName, SqlBuildingContext sqlContext)
        {
            //初始化主查询SQL语句

            var context = sqlContext.DataContext;
            sql.NodeID = CompositeNodeObject.ID;
            sql.CommonObjectID = CompositeDataObject.ID;
            sql.NodeVersion = CompositeDataObject.Version.ToString();
            sql.CommonObjectVersion = CompositeDataObject.Version.ToString();
            sql.TableName = tableName;
            sql.TableCode = tableName;
            sql.SqlBuildingInfo = base.InitSqlBuildingInfo(CompositeDataObject, CompositeNodeObject, dataObject, tableName, sqlContext.DataSource, sqlContext.ControlContext);

            if (context.Data.ContainsKey(CompositeNodeObject.ID))
            {
                var dataContextItem = context.GetCurrentDataContextItem(CompositeNodeObject.ID);
                if (dataContextItem.PrimaryKeyData.Count > 0)
                {
                    foreach (var column in dataObject.PKColumns)
                    {
                        var pkField = new SqlPrimaryKeyField(sql.SqlBuildingInfo.CurrentSqlTable, column.ColumnName);
                        var pkElement = CompositeNodeObject.Elements.FirstOrDefault(i => i.DataColumnID == column.ID);
                        pkField.Value.Value = dataContextItem.PrimaryKeyData[pkElement.ID];
                        pkField.Value.DataType = (int)pkElement.DataType;
                        pkField.Value.DbColumnDataType = column.GetDatabaseColumnType();
                        sql.PrimaryKeys.ChildCollection.Add(pkField);
                    }
                }
            }

            //将子查询加入到当前Select语句中
            sql.From.ChildCollection.Add(sql.SqlBuildingInfo.CurrentSqlTable);
        }

        /// <summary>
        /// 构造处理Select语句中查询字段部分
        /// </summary>
        /// <param name="sql">Select语句</param>
        /// <param name="cno">当前节点对象</param>
        /// <param name="dataObject">当前节点对应的数据对象</param>
        /// <param name="controlContext">控制上下文</param>
        public void BuildQueryFieldList(SelectSqlStatement sql, CompositeNodeObject cno, DataObject dataObject, SqlExecuteControlContext controlContext)
        {
            //var elements = CompositeNodeObject.Elements.Where(i => i.ElementType != ElementType.Virtual || i.ElementType != ElementType.Reference);
            var elements = cno.Elements;  //与上面条件相等

            foreach (var element in elements)
            {
                if (string.IsNullOrEmpty(element.DataColumnID)) continue;
                if (element.ElementType == ElementType.Reference) continue;
                switch (element.ElementType)
                {
                    case ElementType.Normal:
                        {
                            DataColumn column = dataObject.Columns.FirstOrDefault(i => i.ID == element.DataColumnID);
                            if (column == null)
                                throw new FasException(DataAccessErrorCode.CompositeDataObject.ColumnError, string.Format(CommonStringClassEngine.SelectSqlBuildStrategy_BuildQueryFieldList, dataObject.ID, element.DataColumnID));
                            SelectListField field = new SelectListField()
                            {
                                Table = sql.SqlBuildingInfo.CurrentSqlTable,
                                IsUseAlias = true,
                                IsUseFieldPrefix = true,
                                FieldName = column.ColumnName,
                                FieldAlias = element.Alias
                            };
                            sql.SelectList.ChildCollection.Add(field);

                            //统一数据访问服务掩码改造：没有权限的列返回空
                            bool isHavePermission = controlContext.IsHasPermission(dataObject, column);
                            if (!isHavePermission)
                            {
                                field.FieldName = "null";
                                field.IsUseFieldPrefix = false;
                                field.IsExpress = true;
                            }
                            /***************数据国际化改造：CDO.GetDataByID支持多语言列返回****************/
                            if (isHavePermission && column.IsInternational)
                            {
                                var internationalMapping = InternationalTools.GetLanguageMapping(controlContext.InternationalMode, controlContext.SpecifiedLanguages);
                                foreach (var internationalKey in internationalMapping.Keys)
                                {
                                    SelectListField internationalFields = new SelectListField()
                                    {
                                        Table = sql.SqlBuildingInfo.CurrentSqlTable,
                                        IsUseAlias = true,
                                        IsUseFieldPrefix = true,
                                        FieldName = InternationalTools.GetRealFieldName(dataObject, column.ColumnName, internationalKey),
                                        FieldAlias = InternationalTools.GetLogicFieldName(element.Alias, internationalMapping[internationalKey]),
                                    };
                                    sql.SelectList.ChildCollection.Add(internationalFields);
                                }
                            }
                            bool isNotReturnRealData = !isHavePermission || !controlContext.IsCanGetRealData(column);
                            //统一数据访问服务掩码改造
                            if (MaskTool.EnableFASMaskStorage(column.MaskingRule))
                            {
                                string maskFieldName = DataColumn.GetMaskColumnName(dataObject, column.ColumnName);
                                //如果没有权限 或者 没有指定获取真实值，则返回掩码值
                                if (isNotReturnRealData)
                                {
                                    field.FieldName = maskFieldName;
                                    field.IsUseFieldPrefix = true;
                                    field.IsExpress = false;
                                }
                                SelectListField internationalFields = new SelectListField()
                                {
                                    Table = sql.SqlBuildingInfo.CurrentSqlTable,
                                    IsUseAlias = true,
                                    IsUseFieldPrefix = true,
                                    FieldName = maskFieldName,
                                    FieldAlias = DataColumn.GetMaskColumnName(dataObject, element.Alias),
                                };
                                sql.SelectList.ChildCollection.Add(internationalFields);
                            }
                            ////如果没启用掩码、启用了列权限，当有权限 但是没有显示指定获取该列的真实值时，返回空
                            //else if (column.IsEnableColumnPermission && isNotReturnRealData)
                            //{
                            //    field.FieldName = "null";
                            //    field.IsUseFieldPrefix = false;
                            //    field.IsExpress = true;
                            //}
                        }
                        break;
                    case ElementType.Reference:
                        //关联过来的字段不需要在此处理，在关联中处理
                        continue;
                    case ElementType.Enum:
                    case ElementType.Virtual:
                        {
                            var field = new SelectListField()
                            {
                                Table = sql.SqlBuildingInfo.CurrentSqlTable,
                                IsUseAlias = true,
                                IsUseFieldPrefix = true,
                                FieldName = element.DefaultValue,
                                FieldAlias = element.Alias,                                
                            };
                            sql.SelectList.ChildCollection.Add(field);
                        }
                        break;
                }
            } 
        }

       
        #endregion

        /// <summary>
        /// 构造左连接SQL
        /// </summary>
        /// <param name="sql">Select语句</param>
        /// <param name="association">关联</param>
        private void BuildLeftJoin(SelectSqlStatement sql, InternalAssociation association, SqlBuildingContext context)
        {
            LeftJoinItem leftJoin = new LeftJoinItem();
            leftJoin.LeftJoinTable = association.AssociatedTable;
            foreach (var item in association.Association.Items)
            {
                SqlTable srcElelemtTable = association.LocatedTable;
                var srcElement = association.LocatedNode.Elements.FirstOrDefault(i => i.ID == item.SourceElementID);
                /*低代码改动：外键关联DO改造*/
                //targetElement：外键关联DO的列id 
                //左侧CNO节点元素对应的DataObject的列ID
                var leftCol = association.LocatedDataObject.Columns.FirstOrDefault(i => i.ID == srcElement.DataColumnID);
                //右侧AssoDataObject的列ID
                var rightCol = association.AssociatedDataObject.Columns.FirstOrDefault(i => i.ID == item.TargetElementID);

                if (rightCol == null)
                    throw new Exception(string.Format(CommonStringClassEngine.SelectSqlBuildStrategy_AppendQueryRefFields2, association.AssociatedDataObject.Code, item.TargetElementID) + " not exists");

                JoinConditionItem joinItem = new JoinConditionItem();
                joinItem.LeftField.Table = srcElelemtTable;
                joinItem.LeftField.FieldName = leftCol.ColumnName;
                joinItem.LeftField.IsUseFieldPrefix = true;
                joinItem.RightField.Table = association.AssociatedTable;
                joinItem.RightField.FieldName = rightCol.ColumnName;
                joinItem.RightField.IsUseFieldPrefix = true;
                leftJoin.ChildCollection.Add(joinItem);
            }

            //关联上的条件
            leftJoin.AdditionalCondition = this.ParseCondition(association);            

            sql.MainFromItem.ChildCollection.Add(leftJoin);
        }

        private string ParseCondition(InternalAssociation association)
        {
            return association.Association.FilterCondition;
        }

        /// <summary>
        /// 构造Select语句中过滤条件
        /// </summary>  
        /// <remarks>
        /// 根节点和子节点分开处理
        /// </remarks>
        /// <param name="sql">Sql语句对象</param>       
        /// <param name="context">SQL构造上下文</param>
        public void BuildSQLCondition(SelectSqlStatement sql, SqlBuildingContext context)
        {
            //根节点情况
            if (sql.SqlBuildingInfo.CurrentNode.ID == sql.SqlBuildingInfo.CommonObject.RootCompositeNodeObjectID ||
                sql.SqlBuildingInfo.CurrentNode.IsRootObject)
            {
                // 解析授权访问控制的约束条件:主表的查询支持权限关联条件。
                this.ParseSecurityCondition(sql, context);

                // 处理过滤条件中的引用元素
                //this.HandlingFilterConditionRefElement(sql, context.FilterCondition, context);

                // 解析外部传入的过滤条件（表单、帮助、报表等）,注:只处理主对象上的过滤条件。         
                base.GetSelectSqlCondition(sql, context, sql.SqlBuildingInfo.RootNode, sql.SqlBuildingInfo.RootDataObject);

                // 解析过滤条件
                var fiterCondition = base.ParseFilterCondition(sql, context);
                //var fiterCondition = new FilterConditionSpecifySubClassStament(context);
                if (fiterCondition != null)
                {
                    //sql.FilterCondition.ChildCollection.Add(fiterCondition.MainSearchPathConditions);
                    sql.FilterCondition.ChildCollection.Add(fiterCondition);
                }

                // 解析排序条件
                sql.OrderByCondition = base.ParseOrderByCondition(context);

                // 获取前多少条数据。
                if (context.QueryFilter != null && context.QueryFilter.LimitCount > 0)
                {
                    sql.TopSize = context.QueryFilter.LimitCount;
                }
            }
            else // 子节点情况
            {
                var mainDo = context.CommonObject.RootCompositeNodeObject.DataObject;

                // 处理过滤条件中的引用元素
                //this.HandlingFilterConditionRefElement(sql, context.FilterCondition, context);

                // 解析外部传入的过滤条件（表单、帮助、报表等）,注:只处理主对象上的过滤条件。         
                //var filterCondition = base.GeInputCondition(context, sql.SqlBuildingInfo.RootNode,
                //       sql.SqlBuildingInfo.RootDataObject, sql.SqlBuildingInfo);

                //// 解析模型上的过滤条件
                //if (filterCondition != null)
                //    sql.FilterCondition.ChildCollection.Add(filterCondition);
                if (context.DataContext.MainCompositeNodeObject.IsRootObject)
                    base.GetSelectSqlCondition(sql, context, sql.SqlBuildingInfo.RootNode, sql.SqlBuildingInfo.RootDataObject);
                else
                    base.GetSelectSqlCondition(sql, context, sql.SqlBuildingInfo.CurrentNode, sql.SqlBuildingInfo.CurrentDataObject); 
                // 解析排序条件
                sql.OrderByCondition = base.ParseOrderByCondition(context);

                //为子表innerjoin生成与主表一样的过滤条件，否则会造成全表查询。
                //如果需要添加指定子表条件功能，不需要修改context.node，而是根据context.node处理context.QueryFilter.FilterClauses集合
                //集合中的FilterField指定了CompositeNodeObjectElement.ID。根据这个ID遍历有没有当前DO的列
                var fiterCondition = base.ParseFilterCondition(sql, context);
                //var fiterCondition = new FilterConditionSpecifySubClassStament(context);
                if (fiterCondition != null)
                {
                    //sql.FilterCondition.ChildCollection.Add(fiterCondition.MainSearchPathConditions);
                    sql.FilterCondition.ChildCollection.Add(fiterCondition);
                }

                // 获取前多少条数据。
                if (context.QueryFilter != null && context.QueryFilter.LimitCount > 0)
                {
                    sql.TopSize = context.QueryFilter.LimitCount;
                }
            }

            // 分页设置
            if (context.QueryFilter != null && context.QueryFilter.PageParameter != null)
            {
                sql.PageCount = context.QueryFilter.PageParameter.PageSize;
                sql.PageIndex = context.QueryFilter.PageParameter.CurrentPageIndex;
            }
        }      
    }
}
